﻿using Microsoft.Practices.Prism.StoreApps;
using Microsoft.Practices.Prism.StoreApps.Interfaces;
using Microsoft.Practices.Unity;
using Sumc.Client.ModernUI.Common;
using Sumc.Client.ModernUI.Helpers;
using Sumc.Client.ModernUI.Services;
using Sumc.Models.Responses;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using Windows.ApplicationModel.Activation;
using Windows.ApplicationModel.Background;
using Windows.UI.Notifications;

namespace Sumc.Client.ModernUI
{
    public sealed partial class App : MvvmAppBase
    {
        private readonly IUnityContainer container;

        public App()
        {
            this.container = new UnityContainer();
            this.InitializeComponent();
        }

        protected override void OnInitialize(IActivatedEventArgs args)
        {
            this.RegisterTypes();
            ViewModelLocator.SetDefaultViewModelFactory(vm => this.container.Resolve(vm));
            this.RegisterBackgroundTasks();
        }

        protected override IList<SettingsCharmActionItem> GetSettingsCharmActionItems()
        {
            var settingsList = new List<SettingsCharmActionItem>();
            settingsList.Add(new SettingsCharmActionItem("Декларация за поверителност", PrivacyPolicy));
            return settingsList;
        }

        private void PrivacyPolicy()
        {
            this.FlyoutService.ShowFlyout(Constants.PrivacyPolicyFlyout);
        }

        protected override void OnSearchApplication(SearchQueryArguments args)
        {
            if (args != null && !string.IsNullOrWhiteSpace(args.QueryText))
            {
                this.NavigationService.Navigate(Constants.SearchPage, args.QueryText);
            }
            else
            {
                this.NavigationService.Navigate(Constants.HomePage, null);
            }
        }

        protected override void OnLaunchApplication(LaunchActivatedEventArgs args)
        {
            if (string.IsNullOrEmpty(args.Arguments))
            {
                this.NavigationService.Navigate(Constants.HomePage, null);
            }
            else
            {
                this.NavigationService.Navigate(Constants.SchedulePage, args.Arguments);
            }
        }

        protected override void OnRegisterKnownTypesForSerialization()
        {
            this.SessionStateService.RegisterKnownType(typeof(ScheduleDirections));
            this.SessionStateService.RegisterKnownType(typeof(ObservableCollection<string>));
            this.SessionStateService.RegisterKnownType(typeof(Stop));
            this.SessionStateService.RegisterKnownType(typeof(IEnumerable<Stop>));
        }

        private void RegisterTypes()
        {
            this.container.RegisterType<IScheduleRepository, ScheduleRepository>(new ContainerControlledLifetimeManager());
            this.container.RegisterType<IVirtualTableRepository, VirtualTableRepository>(new ContainerControlledLifetimeManager());
            this.container.RegisterType<IStopRepository, StopRepository>(new ContainerControlledLifetimeManager());
            this.container.RegisterType<ISessionRepository, SessionRepository>(new ContainerControlledLifetimeManager());
            this.container.RegisterType<INewsRepository, NewsRepository>(new ContainerControlledLifetimeManager());

            this.container.RegisterType<ISavePickerService, SavePickerService>(new ContainerControlledLifetimeManager());
            this.container.RegisterType<IShareService, ShareService>(new ContainerControlledLifetimeManager());
            this.container.RegisterType<ISearchPaneService, SearchPaneService>(new ContainerControlledLifetimeManager());
            this.container.RegisterType<IAlertMessageService, AlertMessageService>(new ContainerControlledLifetimeManager());
            this.container.RegisterType<ISecondaryTileService, SecondaryTileService>(new ContainerControlledLifetimeManager());

            this.container.RegisterInstance<INavigationService>(this.NavigationService);
            this.container.RegisterInstance<ISessionStateService>(this.SessionStateService);
            this.container.RegisterInstance<IFlyoutService>(FlyoutService);
        }

        private async void RegisterBackgroundTasks()
        {
            try
            {
                var result = await BackgroundExecutionManager.RequestAccessAsync();
                if (result == BackgroundAccessStatus.AllowedMayUseActiveRealTimeConnectivity ||
                    result == BackgroundAccessStatus.AllowedWithAlwaysOnRealTimeConnectivity)
                {
                    var taskName = "SecondaryTileUpdate";
                    var taskEntryPoint = "Sumc.Client.ModernUI.BackgroundTasks.TileUpdate";
                    var condition = new SystemCondition(SystemConditionType.InternetAvailable);
                    var trigger = new TimeTrigger(Constants.TileMinutesUpdatePeriod, false);
                    BackgroundTaskService.RegisterBackgroundTask(taskEntryPoint, taskName, trigger, condition);

                    var internetAvailableTaskName = "InternetAvailableSecondaryTileUpdate";
                    var internetAvailableTrigger = new SystemTrigger(SystemTriggerType.InternetAvailable, false);
                    BackgroundTaskService.RegisterBackgroundTask(taskEntryPoint, internetAvailableTaskName, internetAvailableTrigger);

                    var userPresentTaskName = "UserPresentSecondaryTileUpdate";
                    var userPresentTrigger = new SystemTrigger(SystemTriggerType.UserPresent, false);
                    BackgroundTaskService.RegisterBackgroundTask(taskEntryPoint, userPresentTaskName, userPresentTrigger, condition);

                    var secondTaskName = "SecondSecondaryTileUpdate";
                    var secondTaskEntryPoint = "Sumc.Client.ModernUI.BackgroundTasks.SecondTileUpdate";
                    BackgroundTaskService.RegisterBackgroundTask(secondTaskEntryPoint, secondTaskName, trigger, condition);
                }
            }
            catch { }

            var tileService = new TileService();
            var urls = this.GetUrls();
            tileService.RegisterPeriodicUpdateBatch(urls, PeriodicUpdateRecurrence.SixHours);
        }

        private IEnumerable<string> GetUrls()
        {
            var baseUrl = string.Format("{0}Tiles?number=", Constants.BaseSumcApiUrl);
            for (int i = 0; i < 5; i++)
            {
                yield return baseUrl + i;
            }
        }
    }
}